package com.lcc.lynx.security;

import com.lcc.lynx.common.cache.GroupCache;
import com.lcc.lynx.common.cache.enums.CacheEnum;
import com.lcc.lynx.common.utils.DESUtil;
import com.lcc.lynx.security.config.SecurityProperties;
import com.lcc.lynx.security.pojo.UserInfo;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * 手写session 方便前后端分离
 */
@Component
public class Session {

    private static SecurityProperties securityProperties;

    @Autowired
    public void setSecurityProperties(SecurityProperties securityProperties) {
        Session.securityProperties = securityProperties;
    }

    /**
     * 根据用户名，超时时间（分钟），获取token，并存入用户对象
     *
     * @param user
     * @param req
     * @param resp
     * @return
     */
    public synchronized static String set(UserInfo user, HttpServletRequest req, HttpServletResponse resp) {
        try {
            String token =  DESUtil.encrypt(UUID.randomUUID().toString().replace("-", ""));
            ThreadVariable.localToken.set(token);
            user.setIp(Session.getIpAddress(req));
            user.setUserAgent(req.getHeader("User-Agent"));
            user.setLogin(true);
            user.setToken(token);
            GroupCache.setVal(CacheEnum.token + token, user, securityProperties.getTokenExpire() * 60L);
            Cookie cookie = new Cookie("token", ThreadVariable.localToken.get());
            cookie.setMaxAge(securityProperties.getTokenExpire() * 60);
            cookie.setPath("/");
            resp.addCookie(cookie);
            return token;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("获取token时加密异常");
        }
    }

    public static UserInfo getUserInfo(){
        String token = ThreadVariable.localToken.get();
        if(token == null){
            return null;
        }
        Object o = GroupCache.getVal(CacheEnum.token + token);
        if(o == null){
            return null;
        }
        return (UserInfo) o;
    }

    public static <T>  T getUser(){
        UserInfo userInfo = getUserInfo();
        if(userInfo == null){
            return null;
        }
        return (T) userInfo.getUser();
    }

    public static void logout() {
        GroupCache.delVal(CacheEnum.token + ThreadVariable.localToken.get());
    }

    /**
     * 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址;
     *
     * @param request
     * @return
     */
    public static String getIpAddress(HttpServletRequest request) {
        String ip="";
        try {
            ip = request.getHeader("X-Forwarded-For");
            if (ip != null && ip.length() > 0 && !"unKnown".equalsIgnoreCase(ip)) {
                int index = ip.indexOf(",");
                if (index != -1) {
                    return ip.substring(0, index);
                } else {
                    return ip;
                }
            }
            ip = request.getHeader("X-Real-IP");
            if (ip != null && ip.length() > 0 && !"unKnown".equalsIgnoreCase(ip)) {
                return ip;
            }
            ip= request.getRemoteAddr();
        } catch (Exception ignored) {
        }
        return ip;
    }
}
